Skip to main content

Pathfinding

The board module comes with pathfinding features to ease development of complex behaviour on the board.

BoardPosition

This object is used to represent coordinates on the board. It stores :

  • (x, y) coordinates on the board as integers
  • the orientation on that position (TOP_LEFT, TOP, TOP_RIGHT, RIGHT, BOTTOM_RIGHT, BOTTOM, BOTTOM_LEFT, LEFT)
"""
Class constructor

:param x: integer coordinate on board
:param y: integer coordinate on board
"""
BoardPosition(x, y)

"""
Class constructor

:param x: integer coordinate on board
:param y: integer coordinate on board
:param orientation: module constant
"""
BoardPosition(x, y, orientation)

"""
Class constructor

:param board_position: another board_position to be copied
"""
BoardPosition(board_position)

"""
Returns x coordinate on board (integer)
"""
get_x()

"""
Returns y coordinate on board (integer)
"""
get_y()

"""
Returns orientation on board (constant)
"""
get_orientation()

"""
Returns an array [x, y, orientation]
"""
get()

"""
Set x coordinate

:param x: integer
"""
set_x(x)

"""
Set y coordinate

:param y: integer
"""
set_y(y)

"""
Set orientation

:param orientation: module constant
"""
set_orientation(orientation)

"""
orientation is optional
"""
set(x, y, orientation)

"""
Add the x and y coordinates of another board position

:param board_position: BoardPosition object
"""
add(board_position)

"""
Copy the x, y and orientation values of another board position

:param board_position: BoardPosition object
"""
copy(board_position)

"""
Move by one tile in the given direction in a square board.

:param direction: TOP, RIGHT, BOTTOM, LEFT
"""
move_in_square_board(direction)

"""
Checks if the x, y and orientation values are equal to the ones from another BoardPosition

:param board_position: BoardPosition object

Returns a boolean.
"""
is_equal(board_position)

"""
Print internal values to shell
"""
dump()

"""
Delete the object
"""
__del__()

BoardPath

This object stores an array of positions on the board.

"""
Class constructor
"""
BoardPath()

"""
Append a position to the path

:param board_position: Board position object
"""
append(board_position)

"""
Get the next waypoint in the path

Returns a BoardPosition object
"""
get_next_waypoint()

"""
Print all waypoints
"""
dump()

"""
Destroy object
"""
__del__()

Pathfinder

Used to find a path between two points on the board while avoiding elements.

"""
Class constructor

:param board: Board object
"""
Pathfinder(board)

"""
Find a path between two nodes.

:param start: BoardPosition object containing the coordinates of the starting node
:param end: BoardPosition object containing the coordinates of the end node
:param is_node_walkable_callback: Callback function to be called to check if a node can be walked on

Returns a BoardPath
"""
find_path_to_node(start, end, is_node_walkable_callback)

"""
Destroy object
"""
__del__()

Examples

Basic

import olem
import genericboard

TYPE_START = "start"
TYPE_END = "end"
TYPE_WALL = "wall"

def move_to_board_position(start, position):
y_phys = (position.get_x() - start.get_x()) * 70
x_phys = - (position.get_y() - start.get_y()) * 70

print("(" + str(position.get_x()) + ", " + str(position.get_y()) + ") (" + str(x_phys) + ", " + str(y_phys) + ")")
olem.move_to(x_phys, y_phys, 0)

def find_start_pos(board):
columns = board.get_column_count()
rows = board.get_row_count()

for y in range(rows):
for x in range(columns):
tile = board.get_tile(x, y)
node = tile.get_node()

if (node.has_element_type(TYPE_START)):
return genericboard.BoardPosition(x, y)

def find_end_pos(board):
columns = board.get_column_count()
rows = board.get_row_count()

for y in range(rows):
for x in range(columns):
tile = board.get_tile(x, y)
node = tile.get_node()

if (node.has_element_type(TYPE_END)):
return genericboard.BoardPosition(x, y)

def node_walkable_callback(board, x, y):
# Check if we are on the edge of the board
if (
not board.is_position_within_board(x, y)
or not board.is_position_within_board(x - 1, y)
or not board.is_position_within_board(x, y - 1)
):
return False

if (board.get_column_count() - 1 == x or board.get_row_count() - 1 == y):
return False

# Now checking actual board contents
tile = board.get_tile(x, y)
if (
tile.get_node().has_element_type(TYPE_WALL)
or tile.get_border(0).has_element_type(TYPE_WALL)
or tile.get_border(1).has_element_type(TYPE_WALL)
):
return False

tile = board.get_tile(x - 1, y)
if tile.get_border(0).has_element_type(TYPE_WALL):
return False

tile = board.get_tile(x, y - 1)
if tile.get_border(1).has_element_type(TYPE_WALL):
return False

return True

board = genericboard.load_board("/tmp/board_tester")
board.print()

start = find_start_pos(board)
end = find_end_pos(board)

pf = genericboard.Pathfinder(board)

path = pf.find_path_to_node(start, end, node_walkable_callback)
path.dump()

current_position = genericboard.BoardPosition(start)
while not end.is_equal(current_position):
current_position = path.get_next_waypoint()
move_to_board_position(start, current_position)
olem.wait_stop_moving()

#path.__del__()
#pf.__del__()
#board.__del__()